home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet multimedia / Muzyka / Edytory sampli (probek dzwieku) / ZynAddSubFX_2.2.0 / Setup_ZynAddSubFX-2.2.0.exe / source code / Effects / Echo.C < prev    next >
C/C++ Source or Header  |  2005-03-14  |  5KB  |  241 lines

  1. /*
  2.   ZynAddSubFX - a software synthesizer
  3.  
  4.   Echo.C - Echo effect
  5.   Copyright (C) 2002-2005 Nasca Octavian Paul
  6.   Author: Nasca Octavian Paul
  7.  
  8.   This program is free software; you can redistribute it and/or modify
  9.   it under the terms of version 2 of the GNU General Public License 
  10.   as published by the Free Software Foundation.
  11.  
  12.   This program is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License (version 2) for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License (version 2)
  18.   along with this program; if not, write to the Free Software Foundation,
  19.   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20.  
  21. */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <math.h>
  26. #include "Echo.h"
  27.  
  28. Echo::Echo(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){
  29.     efxoutl=efxoutl_;
  30.     efxoutr=efxoutr_;
  31.     filterpars=NULL;
  32.  
  33.     insertion=insertion_;
  34.     //default values
  35.     Ppreset=0;
  36.     Pvolume=50;
  37.     Ppanning=64; 
  38.     Pdelay=60;
  39.     Plrdelay=100; 
  40.     Plrcross=100; 
  41.     Pfb=40;
  42.     Phidamp=60;
  43.     
  44.     ldelay=NULL;
  45.     rdelay=NULL;
  46.     lrdelay=0;
  47.  
  48.     setpreset(Ppreset);           
  49.     cleanup();
  50. };
  51.  
  52. Echo::~Echo(){
  53.     delete[] ldelay;
  54.     delete[] rdelay;
  55. };
  56.  
  57. /*
  58.  * Cleanup the effect
  59.  */
  60. void Echo::cleanup(){
  61.     int i;
  62.     for (i=0;i<dl;i++) ldelay[i]=0.0;
  63.     for (i=0;i<dr;i++) rdelay[i]=0.0;
  64.     oldl=0.0;
  65.     oldr=0.0;
  66. };
  67.  
  68.  
  69. /*
  70.  * Initialize the delays
  71.  */
  72. void Echo::initdelays(){
  73.     kl=0;kr=0;
  74.     dl=delay-lrdelay;if (dl<1) dl=1;
  75.     dr=delay+lrdelay;if (dr<1) dr=1;
  76.     
  77.     if (ldelay!=NULL) delete [] ldelay;
  78.     if (rdelay!=NULL) delete [] rdelay;
  79.     ldelay=new REALTYPE[dl];
  80.     rdelay=new REALTYPE[dr];
  81.  
  82.     cleanup();
  83. };
  84.  
  85. /*
  86.  * Effect output
  87.  */
  88. void Echo::out(REALTYPE *smpsl,REALTYPE *smpsr){
  89.     int i;
  90.     REALTYPE l,r,ldl,rdl;
  91.  
  92.     for (i=0;i<SOUND_BUFFER_SIZE;i++){
  93.     ldl=ldelay[kl];
  94.     rdl=rdelay[kr];
  95.     l=ldl*(1.0-lrcross)+rdl*lrcross;
  96.     r=rdl*(1.0-lrcross)+ldl*lrcross;
  97.     ldl=l;rdl=r;
  98.     
  99.     efxoutl[i]=ldl*2.0;
  100.     efxoutr[i]=rdl*2.0;
  101.     ldl=smpsl[i]*panning-ldl*fb;
  102.     rdl=smpsr[i]*(1.0-panning)-rdl*fb;
  103.  
  104.     //LowPass Filter
  105.     ldelay[kl]=ldl=ldl*hidamp+oldl*(1.0-hidamp);
  106.     rdelay[kr]=rdl=rdl*hidamp+oldr*(1.0-hidamp);
  107.     oldl=ldl;
  108.     oldr=rdl;
  109.  
  110.     if (++kl>=dl) kl=0;
  111.     if (++kr>=dr) kr=0;
  112.     };
  113.     
  114. };
  115.  
  116.  
  117. /*
  118.  * Parameter control
  119.  */
  120. void Echo::setvolume(unsigned char Pvolume){
  121.     this->Pvolume=Pvolume;
  122.  
  123.     if (insertion==0) {
  124.     outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0;
  125.     volume=1.0;
  126.     } else {
  127.     volume=outvolume=Pvolume/127.0;
  128.     };
  129.     if (Pvolume==0) cleanup();
  130.  
  131. };
  132.  
  133. void Echo::setpanning(unsigned char Ppanning){
  134.     this->Ppanning=Ppanning;
  135.     panning=(Ppanning+0.5)/127.0;
  136. };
  137.  
  138. void Echo::setdelay(unsigned char Pdelay){
  139.     this->Pdelay=Pdelay;
  140.     delay=1+(int)(Pdelay/127.0*SAMPLE_RATE*1.5);//0 .. 1.5 sec
  141.     initdelays();
  142. };
  143.  
  144. void Echo::setlrdelay(unsigned char Plrdelay){
  145.     REALTYPE tmp;
  146.     this->Plrdelay=Plrdelay;    
  147.     tmp=(pow(2,fabs(Plrdelay-64.0)/64.0*9)-1.0)/1000.0*SAMPLE_RATE;
  148.     if (Plrdelay<64.0) tmp=-tmp;
  149.     lrdelay=(int) tmp;
  150.     initdelays();
  151. };
  152.  
  153. void Echo::setlrcross(unsigned char Plrcross){
  154.     this->Plrcross=Plrcross;
  155.     lrcross=Plrcross/127.0*1.0;
  156. };
  157.  
  158. void Echo::setfb(unsigned char Pfb){
  159.     this->Pfb=Pfb;
  160.     fb=Pfb/128.0;
  161. };
  162.  
  163. void Echo::sethidamp(unsigned char Phidamp){
  164.     this->Phidamp=Phidamp;
  165.     hidamp=1.0-Phidamp/127.0;
  166. };
  167.  
  168. void Echo::setpreset(unsigned char npreset){
  169.     const int PRESET_SIZE=7;
  170.     const int NUM_PRESETS=9;
  171.     unsigned char presets[NUM_PRESETS][PRESET_SIZE]={
  172.     //Echo 1
  173.     {67,64,35,64,30,59,0},
  174.     //Echo 2
  175.     {67,64,21,64,30,59,0},
  176.     //Echo 3
  177.     {67,75,60,64,30,59,10},
  178.     //Simple Echo
  179.     {67,60,44,64,30,0,0},
  180.     //Canyon
  181.     {67,60,102,50,30,82,48},
  182.     //Panning Echo 1
  183.     {67,64,44,17,0,82,24},
  184.     //Panning Echo 2
  185.     {81,60,46,118,100,68,18},
  186.     //Panning Echo 3
  187.     {81,60,26,100,127,67,36},
  188.     //Feedback Echo
  189.     {62,64,28,64,100,90,55}};
  190.  
  191.  
  192.     if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1;
  193.     for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]);
  194.     if (insertion!=0) changepar(0,presets[npreset][0]/2);//lower the volume if this is insertion effect
  195.     Ppreset=npreset;
  196. };
  197.  
  198.  
  199. void Echo::changepar(int npar,unsigned char value){
  200.     switch (npar){
  201.     case 0: setvolume(value);
  202.         break;
  203.     case 1: setpanning(value);
  204.         break;
  205.     case 2: setdelay(value);
  206.         break;
  207.     case 3: setlrdelay(value);
  208.         break;
  209.     case 4: setlrcross(value);
  210.         break;
  211.     case 5: setfb(value);
  212.         break;
  213.     case 6: sethidamp(value);
  214.         break;
  215.     };
  216. };
  217.  
  218. unsigned char Echo::getpar(int npar){
  219.     switch (npar){
  220.     case 0: return(Pvolume);
  221.         break;
  222.     case 1: return(Ppanning);
  223.         break;
  224.     case 2: return(Pdelay);
  225.         break;
  226.     case 3: return(Plrdelay);
  227.         break;
  228.     case 4: return(Plrcross);
  229.         break;
  230.     case 5: return(Pfb);
  231.         break;
  232.     case 6: return(Phidamp);
  233.         break;
  234.     };
  235.     return(0);//in case of bogus parameter number
  236. };
  237.  
  238.  
  239.  
  240.  
  241.